﻿using Fungus;
using Harmony;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Logger = BepInEx.Logger;
using BepInEx.Logging;
using CheatMenu.Utils;
using CheatMenu.Menus;
using CheatMenu.Managers;

namespace CheatMenu.Patch
{
    public static class RandomIntegerPatcher
    {
        public static bool Enabled { get; set; } = false;

        static RandomInteger lastInstance;
        static Lazy<MenuRandomIntegerPicker> RandomIntegerPickerMenu = new Lazy<MenuRandomIntegerPicker>(() => MenuManager.GetMenu<MenuRandomIntegerPicker>());

        public static void Patch(HarmonyInstance harmony)
        {
            var original = typeof(RandomInteger).GetMethod("OnEnter");
            var prefix = typeof(RandomIntegerPatcher).GetMethod("prefix_OnEnter");
            var postfix = typeof(RandomIntegerPatcher).GetMethod("postfix_OnEnter");
            harmony.Patch(original, new HarmonyMethod(prefix), new HarmonyMethod(postfix));
        }

        public static void prefix_OnEnter(RandomInteger __instance, ref RandomIntegerPatchState __state)
        {
            if (Enabled)
            {
                IntegerVariable variable = ReflectionUtil.GetVariableFromRandomInteger(__instance);
                if (variable != null)
                {
                    IntegerData min = ReflectionUtil.GetMinValueFromRandomInteger(__instance);
                    IntegerData max = ReflectionUtil.GetMaxValueFromRandomInteger(__instance);
                    __state = new RandomIntegerPatchState(min.Value, max.Value, variable.Key, __instance.ParentBlock?.BlockName);
                    __instance.IsExecuting = false;
                    Logger.Log(LogLevel.Info, $"RandomInteger - Prompting for Value..");
                }
            }
        }

        public static void postfix_OnEnter(RandomInteger __instance, RandomIntegerPatchState __state)
        {
            if (__state != null)
            {
                var menu = RandomIntegerPickerMenu.Value;
                menu.ResetScrollVector();
                menu.ClearCommandGroups();
                menu.HeaderText = $"Block: {__state.BlockName ?? "NULL"}";
                CommandGroup commandGroup = new CommandGroup($"Variable: {__state.VariableKey}");
                for (int i = __state.Min; i < __state.Max; i++)
                {
                    commandGroup.AddCommand(i.ToString(), HandleValueSelected);
                }
                menu.AddCommandGroup(commandGroup);

                lastInstance = __instance;
                menu.Shown = true;
                FungusManager.Instance.CameraManager.Fade(0f, 1f, null);
            }
        }

        private static void HandleValueSelected(Utils.Command command)
        {
            RandomIntegerPickerMenu.Value.Shown = false;
            IntegerVariable variable = ReflectionUtil.GetVariableFromRandomInteger(lastInstance);
            if (int.TryParse(command.Name, out int outValue) && variable != null)
            {
                Logger.Log(LogLevel.Info, $"RandomInteger - Selected Value: {outValue}");
                variable.Value = outValue;
            }
            lastInstance.IsExecuting = true;
            lastInstance.Continue();
        }
    }
}
